#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    if (udpsock) {  // 只有存在时才关闭
            udpsock->close();
            delete udpsock;  // 漏了释放内存，导致内存泄漏
        }
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    if (udpsock) {
            udpsock->close();
            disconnect(udpsock, nullptr, this, nullptr);  // 断开所有信号连接
            delete udpsock;
        }

        // 创建新socket并绑定
        udpsock = new QUdpSocket(this);  // 指定父对象为MainWindow，可自动管理部分生命周期
        bool bindSuccess = udpsock->bind(
            QHostAddress(ui->lineEdit->text()),
            ui->lineEdit_2->text().toInt()
        );

        // 绑定结果提示
        if (bindSuccess) {
            ui->statusbar->showMessage("绑定成功");
            connect(udpsock, &QUdpSocket::readyRead, this, &MainWindow::read);
        } else {
            ui->statusbar->showMessage("绑定失败：" + udpsock->errorString());
            delete udpsock;  // 绑定失败，释放无效对象
            udpsock = nullptr;
        }
}

void MainWindow::on_pushButton_2_clicked()
{
    if (!udpsock) {  // 未初始化
            ui->statusbar->showMessage("请先绑定端口");
            return;
        }

        // 检查是否处于绑定状态（isValid()返回true表示绑定成功）
        if (!udpsock->isValid()) {
            ui->statusbar->showMessage("端口未绑定或绑定失败");
            return;
        }

        QByteArray data = ui->textEdit->toPlainText().toUtf8();
        qint64 bytesSent = udpsock->writeDatagram(
            data,
            QHostAddress(ui->lineEdit_3->text()),
            ui->lineEdit_4->text().toInt()
        );

        // 发送结果提示
        if (bytesSent == -1) {
            ui->statusbar->showMessage("发送失败：" + udpsock->errorString());
        } else {
            ui->statusbar->showMessage("发送成功，" + QString::number(bytesSent) + "字节");
        }
}

void MainWindow::read(){
    char buffer[64] = {0};  // 初始化全 0，避免残留脏数据
        qint64 maxSize = sizeof(buffer);  // 缓冲区最大容量

        // 2. 定义变量存储发送方 IP 和端口（需传指针给 readDatagram）
        QHostAddress senderAddr;
        quint16 senderPort = 0;

    qint64 bytesRead = udpsock->readDatagram(
            buffer,          // 数据缓冲区（char* 类型）
            maxSize,         // 缓冲区最大长度
            &senderAddr,     // 发送方 IP 指针（传出参数）
            &senderPort      // 发送方端口指针（传出参数）
        );
    if (bytesRead > 0) {
            // 将缓冲区数据转换为 QString
            QString data = QString::fromUtf8(buffer, bytesRead);
            qDebug() << "发送方：" << senderAddr.toString() << ":" << senderPort;

            ui->plainTextEdit->appendPlainText("收到：" + data);
        } else if (bytesRead == -1) {
            // 接收失败，打印错误信息
            qDebug() << "UDP 接收失败：" << udpsock->errorString();
        }
}
